package rowan.application.quickaccess.rss;

import java.util.ArrayList;

import rowan.application.quickaccess.rss.parser.ParsedDataSet;
import rowan.application.quickaccess.rss.parser.XmlParser;
import rowan.application.quickaccess.tabs.RSSDisplay;

import android.content.Context;
import android.database.Cursor;
import android.util.Log;

/**
 * This class is the database helper/manager
 * 
 * Get the feeds, fill in feeds. Parses the info into a parsedDataSet.
 * 		
 * Features to improve performance is enchance the SAXParser so it doesn't need to parse the entire file?
 * 		Maybe push in database rows instead of deleteing the entire table
 * 
 * 
 * @author Tom
 *
 */
public class RssDbHelper {
	private RssDbAdapter mDbAdapter;
	private RssFeed[] rssFeeds;
	
	/** 
	 * Constructor
	 * @param context The context
	 */
	public RssDbHelper(Context context)
	{
		mDbAdapter = new RssDbAdapter(context);
		createRssFeeds();
	}
	
	/**
	 * Creates the Rss Feeds that are going to be stored in the database with their feed ID, url and table name
	 */
	@SuppressWarnings("static-access")
	private void createRssFeeds()
	{
	   rssFeeds = new RssFeed[3]; // we have 3 feeds
       rssFeeds[0] = new RssFeed("http://www.rowan.edu/today/news/HPNewsRSS", RSSDisplay.ROWAN_FEED, mDbAdapter.DATABASE_TABLE);
       rssFeeds[1] = new RssFeed("http://twitter.com/statuses/user_timeline/21661387.rss", RSSDisplay.TWITTER_FEED, mDbAdapter.DATABASE_TABLE_TWITTER);
       rssFeeds[2] = new RssFeed("http://www.rowanathletics.com/rss.aspx", RSSDisplay.SPORTS_FEED, mDbAdapter.DATABASE_TABLE_SPORTS);
	       
	}
	
	/** 
	 * Given a feedType, this method returns the assigned RssFeed
	 * 
	 * @param feedID FeedID Given
	 * @return The RssFeed which contains the feed Url, feedID, and database table name
	 */
	public RssFeed getRssFeed(int feedID)
	{
		for (RssFeed rssFeed : rssFeeds)
		{
			if (rssFeed.getFeedID() == feedID)
				return rssFeed;
		}
		return null;
	}
	
    /** Fills the database with any new information based on a freshly parsed DataSet
     * 		and a ParsedDataSet created from getDatabase()
     * 
     * Limit 11 items, this includes the rss feeds header item
     * 
     * If nothing exists in the database, the new data will go straight into the database
     * 
     * 
     * this method could use some cleanup... 
     * 
     * @param feedID The ID of the feed being updated
     */
    public ParsedDataSet fillDataBase(int feedID)
    {
    	RssFeed rssFeed = getRssFeed(feedID);
    	byte[] image = new byte[0]; // pretty much a null placeholder
    	int newItems =0;
    	
    	ParsedDataSet newDataList = new ParsedDataSet();
    	ParsedDataSet currentData = getDatabase(rssFeed.getFeedID());
    	ParsedDataSet newData = parse(rssFeed.getUrl());  // MAYBE WE CAN LINK FEED TYPE TO THE URL Hashmap<type,url>
	    	
	    	
    	if (currentData==null) // nothing has been stored yet
    	{
    		int entries = newData.getTitles().size(); // don't add anything
    		if (entries> 11)
    		{
    			entries = 11;
    		}
    		for (int i=0; i<entries; i++)
    		{
				mDbAdapter.createEntry(newData.getTitles().get(i), newData.getDescs().get(i), 
					newData.getLinks().get(i), image, rssFeed.getTable());
    		}
    	}
    	else
    	{
		// we are going to assume the current parsedDataSet is new data
//    	
		boolean noMatch = true;
		int i=1; // Starts at 1 because the feed always has the beginning deafault item
										newDataList.addTitle(currentData.getTitles().get(0));
										newDataList.addDesc(currentData.getDescs().get(0));
										newDataList.addLink(currentData.getLinks().get(0));

		while(noMatch && newData.getTitles().size()>1 && i<newData.getTitles().size())
		{
			String newTitle = newData.getTitles().get(i);
//    			String oldTitle = currentData.getTitles().get(i);
			
			if (!checkForDuplicates(currentData, newTitle))
				// we aren't going to do anything
				noMatch=false;
			else {
				newDataList.addTitle(newTitle);
				newDataList.addDesc(newData.getDescs().get(i)+"");
				newDataList.addLink(newData.getLinks().get(i));

				newItems = i;
				i++;
			}
		}
		int entries = currentData.getTitles().size()+newDataList.getTitles().size()-1;
		if (entries > 11)
			entries = 11;
//    		if (entries == 10)
//    			entries = 9;
											
		for (int j=1; j< currentData.getTitles().size(); j++)
		{
			newDataList.addTitle(currentData.getTitles().get(j));
			newDataList.addDesc(currentData.getDescs().get(j) +"");
			newDataList.addLink(currentData.getLinks().get(j));

		}
	
    	mDbAdapter.clearTable(rssFeed.getTable());
    	for (int k=0; k<entries; k++)
    	{

    		mDbAdapter.createEntry(newDataList.getTitles().get(k), newDataList.getDescs().get(k), 
    							newDataList.getLinks().get(k), image, rssFeed.getTable());
    	}
       }
	    	
	    	ParsedDataSet updatedFeed = getDatabase(rssFeed.getFeedID());
	    	if (newItems>10)
	    		newItems = 10;
	    	updatedFeed.setNumOfNewItems(newItems);
	    	return updatedFeed;
    }
    
	
	
    /**
     * Gets the database in storage under the table given
     * 
     * @param feedID the ID of the feed being requested
     * @return ParsedDataSet of the data stored under the table
     */
    public ParsedDataSet getDatabase(int feedID)
    {
    	RssFeed rssFeed = getRssFeed(feedID);
    	
    	ParsedDataSet tempDS = null;
		try {
    	// Make methods that fetch all the information from database given the table
			Cursor c = mDbAdapter.fetchAllEntries(rssFeed.getTable());
//		startManagingCursor(c);
		
			while(c.moveToNext()){
				if (c.isFirst())
					tempDS = new ParsedDataSet();
				String title = c.getString(1);
				String desc = c.getString(2)+ "";
				String link = c.getString(3);
//				byte[] image=null;
//				if (feedID == RSSDisplay.SPORTS_FEED){
//					image = c.getBlob(4);
//				if (image.length != 0)
//					tempDS.addImg(image);
//				}
				tempDS.addTitle(title);
				tempDS.addDesc(desc);
				tempDS.addLink(link);
			}
			c.close();
		}
		catch (Exception e)
		{
			Log.i(this.toString(), "ERROR " +e.toString());
		}
		
		return tempDS;
    }
    
    
    public boolean update()
    {
    	// see if we should update; if the data is old enough, we update
    	return false;
    }
    
    public void open()
    {
    	mDbAdapter.open();
    }
    
    public void close()
    {
    	mDbAdapter.close();
    }

    
    /** Parse the given url and returns the parsedDataSet
     * 
     * @param url The url being parsed
     * @return ParsedDataSet of information retreived from parsing, null if failure
     *  */
    public ParsedDataSet parse(String url)
    {
    	
        try {
        	XmlParser xmlParser = new XmlParser();
        	xmlParser.parseURL(url);
        	return xmlParser.getDataSet();
        }
        catch (Exception e) { 
        	
        }
        return null;
    }
    
    
	
	 /**
     * Checks everything in the parsedDataSet db to make sure no titles match newTitle
     * 
     * @param db ParsedDataSet of information already in the db
     * @param newTitle The title of the new item being checked
     * @return True if there are no duplicates, false if there is a duplicate
     */
    private boolean checkForDuplicates(ParsedDataSet db, String newTitle)
    {
    	ArrayList<String> titles = db.getTitles();
    	for (String title : titles)
    		if (title.equals(newTitle))
    			return false;
    	return true;
    }
    
}